home *** CD-ROM | disk | FTP | other *** search
- /*EM BOGUS.C - Bogus Device Driver DLL
- *
- * SUMMARY
- * Basic LibMain and WEP functions
- *
- * COMMENTS
- *
- * WARNINGS
- *
- */
-
-
- #include <windows.h>
- #include "bogusa.h"
- #include "pic.h"
- #include "dpmi.h"
-
- #define EXPORT _export _loadds
- #include "bogus.h"
-
- #define FAKE_PORT 0x141 /* Bogosity Level = 9.4 */
- #define FAKE_IRQ 11 /* Bogosity Level = 9.8 */
-
- #define FAKE_CTL_START 0x01 /* bogus port start command (set to zero) */
- #define FAKE_CTL_EOI 0x02 /* bogus port EOI (set to zero) */
-
- #define FAKE_STAT_BUSY 0x01 /* bogus port busy indication (zero=>busy) */
- #define FAKE_STAT_IRQ 0x02 /* bogus port IRQ (zero=>IRQ) */
- #define FAKE_STAT_ERROR 0x04 /* I/O error (zero=>error) (cleared on read) */
-
-
- /* Set variables for our interrupt number */
-
- #if (FAKE_IRQ < 8)
- #define INT_DEV (INT_MASTER_0+(FAKE_IRQ & 7))
- #define PIC00 INTA00
- #define PIC01 INTA01
- #else
- #define INT_DEV (INT_SLAVE_0+(FAKE_IRQ & 7))
- #define PIC00 INTB00
- #define PIC01 INTB01
- #endif
- #define INT_MASK (1 << (FAKE_IRQ & 7))
-
-
- BOOL FAR PASCAL LibMain(HANDLE hInstance /* Library instance handle */
- ,WORD wDataSeg /* Default data segment */
- ,WORD cbHeap /* Default Heap size */
- ,LPSTR lpszCmdLine) ;/* Command line */
- int FAR PASCAL WEP(int fSystemExit) ;
- #pragma alloc_text(INIT_TEXT,LibMain) /* Keep this with LIBENTRY.ASM */
- #pragma alloc_text(FIXED_TEXT,WEP)
-
- HANDLE hLibInstance ;
- FARPROC lpfnPrevISR ; /* Saved Previous ISR */
- DWORD lpfnPrevRMISR ; /* Saved Previous real-mode ISR */
- HANDLE hReflector ;
-
- DWORD DPMI_AllocateRMCallback(FARPROC lpfnCallback, _RMCS FAR *lpRMCS)
- {
- DWORD dwRet ;
- _asm {
- push ds
- lds si,lpfnCallback
- les di,lpRMCS
- mov ax,DPMI_ALLOCRMC
- int IVEC_DPMI
- pop ds
- jc lbl1
- mov word ptr dwRet,dx ; return callback address
- mov word ptr dwRet+2,cx
- jmp short lbl2
- lbl1:
- mov word ptr dwRet,ax ; error code in ax
- mov word ptr dwRet+2,0 ; return seg=0 if error
- lbl2:
- }
-
- return dwRet ;
- }
-
-
- WORD DPMI_FreeRMCallback(DWORD lpfnCallback)
- {
- WORD wRet ;
-
- _asm {
- mov dx,word ptr lpfnCallback
- mov cx,word ptr lpfnCallback+2
- mov ax,DPMI_FREERMC
- int IVEC_DPMI
- jc lbl1
- xor ax,ax
- lbl1:
- mov wRet,ax
- }
- return wRet ;
- }
-
-
- DWORD DPMI_GetRMVector(int iVector)
- {
- DWORD dwRet ;
- _asm {
- mov ax,DPMI_GETRMVEC
- mov bl,byte ptr iVector
- int 31h
- mov word ptr dwRet,dx
- mov word ptr dwRet+2,cx
- }
- return dwRet ;
- }
-
-
- void DPMI_SetRMVector(int iVector, DWORD lpfnRMISR)
- {
- _asm {
- mov ax,DPMI_SETRMVEC
- mov bl,byte ptr iVector
- mov dx,word ptr lpfnRMISR
- mov cx,word ptr lpfnRMISR+2
- int 31h
- }
- }
-
-
- FARPROC GetPMVector(int iVector)
- {
- FARPROC dwRet ;
-
- _asm {
- mov al,byte ptr iVector
- mov ah,35h
- int 21h
- mov word ptr dwRet,bx
- mov word ptr dwRet+2,es ; Save it
- }
- return dwRet ;
- }
-
-
- void SetPMVector(int iVector, FARPROC lpfnISR)
- {
- _asm {
- push ds
- lds dx,lpfnISR
- mov al,byte ptr iVector
- mov ah,25h
- int 21h ; Set our ISR
- pop ds
- }
- }
-
-
- HANDLE AllocIntReflector(int iVector, FARPROC lpfnCallback)
- {
- DWORD dwDosMem ;
- LPSTR lpLowRMISR ;
- DWORD lpfnRMCallback ;
- _RMCS FAR *lpSaveRegs ;
-
- /* Allocate some DOS memory for the Real-mode Interrupt service routine */
-
- dwDosMem = GlobalDosAlloc(16 + sizeof (int) + sizeof (_RMCS)) ;
-
- if (dwDosMem == 0)
- return 0 ;
- lpLowRMISR = (LPSTR) MAKELONG(0,LOWORD(dwDosMem)) ;
- lpSaveRegs = (_RMCS FAR *) (&lpLowRMISR[16]) ;
-
- /* Allocate a real-mode callback */
-
- lpfnRMCallback = DPMI_AllocateRMCallback((FARPROC)lpfnCallback,lpSaveRegs)
- ;
- if (HIWORD((DWORD)lpfnRMCallback) == 0)
- {
- GlobalDosFree(LOWORD(dwDosMem)) ;
- return 0;
- }
-
- /* Generate the low-memory code (it's only 6 bytes) */
-
- lpLowRMISR[0] = 0x9A ; /* CALL FAR PTR */
- *((DWORD FAR *)&(lpLowRMISR[1])) = lpfnRMCallback ;
- lpLowRMISR[5] = 0xCF ; /* IRET */
- *((int FAR *)&(lpLowRMISR[6])) = iVector ;
-
- /* hook the real mode interrupt vector */
- DPMI_SetRMVector(iVector,MAKELONG(0,HIWORD(dwDosMem))) ;
-
- return (HANDLE) LOWORD(dwDosMem) ; /* return the reflector handle */
- }
-
-
- void FreeIntReflector(HANDLE hReflector)
- {
- LPSTR lpLowRMISR ;
- DWORD lpfnRMCallback ;
-
- /* Get the protected mode address of the low ISR */
-
- lpLowRMISR = (LPSTR)MAKELONG(0,(WORD)hReflector) ;
-
-
- /* make sure that it's a reflector */
- if ((lpLowRMISR[0] != 0x9A) || (lpLowRMISR[5] != 0xCF))
- return ; /* exit if not a reflector */
-
-
- /* Extract the callback address and free the callback */
-
- lpfnRMCallback = *((DWORD FAR *)&(lpLowRMISR[1])) ;
- DPMI_FreeRMCallback(lpfnRMCallback) ;
-
-
- /* free the real-mode interrupt service routine */
-
- GlobalDosFree((WORD) hReflector) ;
- }
-
-
- /*XP< LibMain - Main library entry point.
- *
- * ENTRY
- *
- * EXIT
- *
- * RETURNS
- * TRUE if initialization succeeds, FALSE otherwise.
- *
- * WARNINGS
- *
- * CALLS
- *
- * NOTES
- * The true library entry point is in the assembly language
- * module LIBENTRY.ASM, but it simply passes control to here.
- *
- */
- BOOL FAR PASCAL LibMain(HANDLE hInstance /* Library instance handle */
- ,WORD wDataSeg /* Default data segment */
- ,WORD cbHeap /* Default Heap size */
- ,LPSTR lpszCmdLine) /* Command line */
- /*>*/
- {
- lpszCmdLine = lpszCmdLine ; /* Avoid -W4 warnings */
- wDataSeg = wDataSeg ;
- cbHeap = cbHeap ;
- hLibInstance = hInstance ; /* We may need this later to access
- resources from our executable */
-
-
- return TRUE ;
- }
-
-
-
- /*XP< WEP - Windows Exit Procedure
- *
- * ENTRY
- * fSystemExit indicates if we are terminating the Windows
- * session. Otherwise, we are only unloading this DLL.
- *
- * RETURNS
- * Always returns "1".
- *
- * WARNINGS
- * Due to bugs in Windows 3.0 and earlier (and perhaps later),
- * this function must be placed in a fixed segment. This same
- * bug makes the value of DS questionable, so we cannot use it
- * (or any static data).
- *
- * To be sure, we don't do anything here, anyway.
- *
- * CALLS
- * None
- *
- * NOTES
- * This is the standard DLL exit procedure.
- *
- */
- int FAR PASCAL WEP(int fSystemExit)
- /*>*/
- {
- fSystemExit = fSystemExit ; /* Avoid -W4 warning */
- return 1 ; /* Always indicate success */
- }
-
-
- int EXPORT FAR PASCAL BogusCheck(void)
- {
- BYTE bPortVal ;
-
- _asm {
- mov dx,FAKE_PORT
- in al,dx ; Is the bogus device present ?
- mov bPortVal,al
- }
-
- return ((bPortVal & 0x80) == 0) ; /* Return TRUE if device is present */
- }
-
-
- void EXPORT FAR PASCAL BogusStart(HWND hWnd, WPARAM wParam)
- {
- wParamEvent = wParam ;
- hWndEvent = hWnd ;
-
- if (!lpfnPrevISR)
- {
- /* Save the previous ISR and set ours */
- _asm cli
- lpfnPrevISR = GetPMVector(INT_DEV) ;
- SetPMVector(INT_DEV,(FARPROC)IntSvcRtn) ;
- _asm sti
-
- /* Save the previous real mode ISR and reflect to ours */
- lpfnPrevRMISR = DPMI_GetRMVector(INT_DEV) ;
- hReflector = AllocIntReflector(INT_DEV,(FARPROC)BogusCallback) ;
-
- /* Unmask the interrupt and begin device I/O */
- _asm {
- cli
- in al,PIC01 ; unmask the interrupt
- and al,NOT INT_MASK
- out PIC01,al
- sti
- mov al,NOT FAKE_CTL_START
- mov dx,FAKE_PORT
- out dx,al ; start device I/O
- }
- }
- }
-
-
- int EXPORT FAR PASCAL BogusGetEvent(void)
- {
- WORD wCountRet ;
-
- _asm {
- mov ax,SEG wCount
- mov es,ax
- xor ax,ax
- xchg ax,es:wCount ; get count, set to zero
- mov wCountRet,ax
- }
-
- return wCountRet ;
- }
-
-
- void EXPORT FAR PASCAL BogusStop(void)
- {
- hWndEvent = 0x0000 ; /* Tell the ISR to stop */
-
- if (!lpfnPrevISR)
- return ; /* return if not started */
-
- _asm {
- mov dx,FAKE_PORT
- l1:
- in al,dx
- rcr al,1
- jnc l1 ; loop while busy
-
- cli
- in al,PIC01
- or al,INT_MASK
- out PIC01,al ; mask the interrupt level
- sti
- }
-
- DPMI_SetRMVector(INT_DEV, lpfnPrevRMISR) ; /* Restore real-mode vector */
- FreeIntReflector(hReflector) ; /* Free the reflector */
- SetPMVector(INT_DEV, lpfnPrevISR) ; /* Restore the prot-mode vector */
-
- lpfnPrevISR = NULL ;
- }
-